#pragma once
#include "type.h"
using namespace std;


class AtomicType :public Type{
	
	
public:
	//Type overides
	bool isAtomicType() const {return true;};
	virtual bool isFreeTypeVariable() const = 0;
	virtual bool isBoundedTypeVariable() const = 0;
	
public:
	//Token overides
	Token::pointer applyArgument(Token::const_reference)  const;

public:
	AtomicType(const string& ="");
	AtomicType(const AtomicType&);
	virtual ~AtomicType();

	};

class FreeTypeVariable : public AtomicType{

public:
	bool isFreeTypeVariable() const {return true;};
	bool isBoundedTypeVariable() const {return false;};

public:
	FreeTypeVariable(const string& ="");
	FreeTypeVariable(const FreeTypeVariable&);
	virtual ~FreeTypeVariable();
	Token::pointer clone() const;
	};


class BoundedTypeVariable : public AtomicType{

public:
	bool isFreeTypeVariable() const {return false;};
	bool isBoundedTypeVariable() const {return true;};

public:
	BoundedTypeVariable(const string& ="");
	BoundedTypeVariable(const BoundedTypeVariable&);
	virtual ~BoundedTypeVariable();
	Token::pointer clone() const;
	};